#ifndef LEXER_H
#define LEXER_H

#include <string>
#include <vector>
#include <unordered_map>
#include <stdexcept>

enum class TokenType {
    KEYWORD, IDENTIFIER, CONST_INT, CONST_STRING, OPERATOR, DELIMITER, END, ERROR
};

struct Token {
    TokenType type;
    std::string value;
    int line;
    int column;

    Token(TokenType t, const std::string& v, int l, int c)
        : type(t), value(v), line(l), column(c) {
    }
};

class LexerError : public std::runtime_error {
public:
    LexerError(const std::string& msg, int line, int col)
        : std::runtime_error("[LEXER_ERROR, " + std::to_string(line) + ", " + std::to_string(col) + "] " + msg) {}
};

class Lexer {
public:
    Lexer(const std::string& input);
    std::vector<Token> tokenize();

private:
    char peek() const;
    char peek(int offset) const;
    char advance();
    void skipWhitespace();
    Token readNextToken();
    Token readNumber();
    Token readString();
    Token readIdentifier();
    Token readOperator();

    std::string input;
    size_t pos;
    int line;
    int column;

    static const std::unordered_map<std::string, TokenType> keywords;
};

#endif // LEXER_H